home *** CD-ROM | disk | FTP | other *** search
/ Amiga Games Extra 1996 September / Amiga Games Extra CD-ROM 9-1996.iso / userbox / publicdomain / vim-4.2 / src / tables.c < prev    next >
C/C++ Source or Header  |  1996-06-09  |  13KB  |  478 lines

  1. /* vi:set ts=4 sw=4:
  2.  *
  3.  * VIM - Vi IMproved        by Bram Moolenaar
  4.  *                            This file by Robert Webb
  5.  *
  6.  * Do ":help uganda"  in Vim to read copying and usage conditions.
  7.  * Do ":help credits" in Vim to see a list of people who contributed.
  8.  */
  9.  
  10. /*
  11.  * tables.c: functions that use lookup tables for various things, generally to
  12.  * do with special key codes.
  13.  */
  14.  
  15. #include "vim.h"
  16. #include "globals.h"
  17. #include "proto.h"
  18. #include "option.h"
  19.  
  20. /*
  21.  * Some useful tables.
  22.  */
  23.  
  24. static struct
  25. {
  26.     int        mod_mask;        /* Bit-mask for particular key modifier */
  27.     char_u    name;            /* Single letter name of modifier */
  28. } mod_mask_table[] =
  29. {
  30.     {MOD_MASK_ALT,        (char_u)'M'},
  31.     {MOD_MASK_CTRL,        (char_u)'C'},
  32.     {MOD_MASK_SHIFT,    (char_u)'S'},
  33.     {MOD_MASK_2CLICK,    (char_u)'2'},
  34.     {MOD_MASK_3CLICK,    (char_u)'3'},
  35.     {MOD_MASK_4CLICK,    (char_u)'4'},
  36.     {0x0,                NUL}
  37. };
  38.  
  39. /*
  40.  * Shifted key terminal codes and their unshifted equivalent.
  41.  * Don't add mouse codes here, they are handled seperately!
  42.  */
  43. static char_u shifted_keys_table[] =
  44. {
  45. /*  shifted                 unshifted  */
  46.     '&', '9',                '@', '1',            /* begin */
  47.     '&', '0',                '@', '2',            /* cancel */
  48.     '*', '1',                '@', '4',            /* command */
  49.     '*', '2',                '@', '5',            /* copy */
  50.     '*', '3',                '@', '6',            /* create */
  51.     '*', '4',                'k', 'D',            /* delete char */
  52.     '*', '5',                'k', 'L',            /* delete line */
  53.     '*', '7',                '@', '7',            /* end */
  54.     '*', '9',                '@', '9',            /* exit */
  55.     '*', '0',                '@', '0',            /* find */
  56.     '#', '1',                '%', '1',            /* help */
  57.     '#', '2',                'k', 'h',            /* home */
  58.     '#', '3',                'k', 'I',            /* insert */
  59.     '#', '4',                'k', 'l',            /* left arrow */
  60.     '%', 'a',                '%', '3',            /* message */
  61.     '%', 'b',                '%', '4',            /* move */
  62.     '%', 'c',                '%', '5',            /* next */
  63.     '%', 'd',                '%', '7',            /* options */
  64.     '%', 'e',                '%', '8',            /* previous */
  65.     '%', 'f',                '%', '9',            /* print */
  66.     '%', 'g',                '%', '0',            /* redo */
  67.     '%', 'h',                '&', '3',            /* replace */
  68.     '%', 'i',                'k', 'r',            /* right arrow */
  69.     '%', 'j',                '&', '5',            /* resume */
  70.     '!', '1',                '&', '6',            /* save */
  71.     '!', '2',                '&', '7',            /* suspend */
  72.     '!', '3',                '&', '8',            /* undo */
  73.     KS_EXTRA, KE_S_UP,        'k', 'u',            /* up arrow */
  74.     KS_EXTRA, KE_S_DOWN,    'k', 'd',            /* down arrow */
  75.  
  76.     KS_EXTRA, KE_S_F1,      'k', '1',            /* F1 */
  77.     KS_EXTRA, KE_S_F2,      'k', '2',
  78.     KS_EXTRA, KE_S_F3,      'k', '3',
  79.     KS_EXTRA, KE_S_F4,      'k', '4',
  80.     KS_EXTRA, KE_S_F5,      'k', '5',
  81.     KS_EXTRA, KE_S_F6,      'k', '6',
  82.     KS_EXTRA, KE_S_F7,      'k', '7',
  83.     KS_EXTRA, KE_S_F8,      'k', '8',
  84.     KS_EXTRA, KE_S_F9,      'k', '9',
  85.     KS_EXTRA, KE_S_F10,     'k', ';',            /* F10 */
  86.  
  87.     KS_EXTRA, KE_S_F11,     'F', '1',
  88.     KS_EXTRA, KE_S_F12,     'F', '2',
  89.     KS_EXTRA, KE_S_F13,     'F', '3',
  90.     KS_EXTRA, KE_S_F14,     'F', '4',
  91.     KS_EXTRA, KE_S_F15,     'F', '5',
  92.     KS_EXTRA, KE_S_F16,     'F', '6',
  93.     KS_EXTRA, KE_S_F17,     'F', '7',
  94.     KS_EXTRA, KE_S_F18,     'F', '8',
  95.     KS_EXTRA, KE_S_F19,     'F', '9',
  96.     KS_EXTRA, KE_S_F20,     'F', 'A',
  97.  
  98.     KS_EXTRA, KE_S_F21,     'F', 'B',
  99.     KS_EXTRA, KE_S_F22,     'F', 'C',
  100.     KS_EXTRA, KE_S_F23,     'F', 'D',
  101.     KS_EXTRA, KE_S_F24,     'F', 'E',
  102.     KS_EXTRA, KE_S_F25,     'F', 'F',
  103.     KS_EXTRA, KE_S_F26,     'F', 'G',
  104.     KS_EXTRA, KE_S_F27,     'F', 'H',
  105.     KS_EXTRA, KE_S_F28,     'F', 'I',
  106.     KS_EXTRA, KE_S_F29,     'F', 'J',
  107.     KS_EXTRA, KE_S_F30,     'F', 'K',
  108.  
  109.     KS_EXTRA, KE_S_F31,     'F', 'L',
  110.     KS_EXTRA, KE_S_F32,     'F', 'M',
  111.     KS_EXTRA, KE_S_F33,     'F', 'N',
  112.     KS_EXTRA, KE_S_F34,     'F', 'O',
  113.     KS_EXTRA, KE_S_F35,     'F', 'P',
  114.  
  115.     KS_EXTRA, KE_S_TAB,     KS_EXTRA, KE_TAB,    /* TAB */
  116.     NUL
  117. };
  118.  
  119. static struct key_name_entry
  120. {
  121.     int        key;        /* Special key code or ascii value */
  122.     char_u    *name;        /* Name of key */
  123. } key_names_table[] =
  124. {
  125.     {' ',                (char_u *)"Space"},
  126.     {TAB,                (char_u *)"Tab"},
  127.     {K_TAB,                (char_u *)"Tab"},
  128.     {NL,                (char_u *)"NL"},
  129.     {NL,                (char_u *)"NewLine"},    /* Alternative name */
  130.     {NL,                (char_u *)"LineFeed"},    /* Alternative name */
  131.     {NL,                (char_u *)"LF"},        /* Alternative name */
  132.     {CR,                (char_u *)"CR"},
  133.     {CR,                (char_u *)"Return"},    /* Alternative name */
  134.     {ESC,                (char_u *)"Esc"},
  135.     {K_UP,                (char_u *)"Up"},
  136.     {K_DOWN,            (char_u *)"Down"},
  137.     {K_LEFT,            (char_u *)"Left"},
  138.     {K_RIGHT,            (char_u *)"Right"},
  139.  
  140.     {K_F1,                 (char_u *)"F1"},
  141.     {K_F2,                 (char_u *)"F2"},
  142.     {K_F3,                 (char_u *)"F3"},
  143.     {K_F4,                 (char_u *)"F4"},
  144.     {K_F5,                 (char_u *)"F5"},
  145.     {K_F6,                 (char_u *)"F6"},
  146.     {K_F7,                 (char_u *)"F7"},
  147.     {K_F8,                 (char_u *)"F8"},
  148.     {K_F9,                 (char_u *)"F9"},
  149.     {K_F10,                (char_u *)"F10"},
  150.  
  151.     {K_F11,                (char_u *)"F11"},
  152.     {K_F12,                (char_u *)"F12"},
  153.     {K_F13,                (char_u *)"F13"},
  154.     {K_F14,                (char_u *)"F14"},
  155.     {K_F15,                (char_u *)"F15"},
  156.     {K_F16,                (char_u *)"F16"},
  157.     {K_F17,                (char_u *)"F17"},
  158.     {K_F18,                (char_u *)"F18"},
  159.     {K_F19,                (char_u *)"F19"},
  160.     {K_F20,                (char_u *)"F20"},
  161.  
  162.     {K_F21,                (char_u *)"F21"},
  163.     {K_F22,                (char_u *)"F22"},
  164.     {K_F23,                (char_u *)"F23"},
  165.     {K_F24,                (char_u *)"F24"},
  166.     {K_F25,                (char_u *)"F25"},
  167.     {K_F26,                (char_u *)"F26"},
  168.     {K_F27,                (char_u *)"F27"},
  169.     {K_F28,                (char_u *)"F28"},
  170.     {K_F29,                (char_u *)"F29"},
  171.     {K_F30,                (char_u *)"F30"},
  172.  
  173.     {K_F31,                (char_u *)"F31"},
  174.     {K_F32,                (char_u *)"F32"},
  175.     {K_F33,                (char_u *)"F33"},
  176.     {K_F34,                (char_u *)"F34"},
  177.     {K_F35,                (char_u *)"F35"},
  178.  
  179.     {K_HELP,            (char_u *)"Help"},
  180.     {K_UNDO,            (char_u *)"Undo"},
  181.     {K_BS,                (char_u *)"BS"},
  182.     {K_BS,                (char_u *)"BackSpace"},    /* Alternative name */
  183.     {K_INS,                (char_u *)"Insert"},
  184.     {K_INS,                (char_u *)"Ins"},        /* Alternative name */
  185.     {K_DEL,                (char_u *)"Del"},
  186.     {K_DEL,                (char_u *)"Delete"},    /* Alternative name */
  187.     {K_HOME,            (char_u *)"Home"},
  188.     {K_END,                (char_u *)"End"},
  189.     {K_PAGEUP,            (char_u *)"PageUp"},
  190.     {K_PAGEDOWN,        (char_u *)"PageDown"},
  191.     {K_MOUSE,            (char_u *)"Mouse"},
  192.     {K_LEFTMOUSE,        (char_u *)"LeftMouse"},
  193.     {K_LEFTDRAG,        (char_u *)"LeftDrag"},
  194.     {K_LEFTRELEASE,        (char_u *)"LeftRelease"},
  195.     {K_MIDDLEMOUSE,        (char_u *)"MiddleMouse"},
  196.     {K_MIDDLEDRAG,        (char_u *)"MiddleDrag"},
  197.     {K_MIDDLERELEASE,    (char_u *)"MiddleRelease"},
  198.     {K_RIGHTMOUSE,        (char_u *)"RightMouse"},
  199.     {K_RIGHTDRAG,        (char_u *)"RightDrag"},
  200.     {K_RIGHTRELEASE,    (char_u *)"RightRelease"},
  201.     {K_ZERO,            (char_u *)"Nul"},
  202.     {0,                    NULL}
  203. };
  204.  
  205. #define KEY_NAMES_TABLE_LEN (sizeof(key_names_table) / sizeof(struct key_name_entry))
  206.  
  207. #ifdef USE_MOUSE
  208. static struct
  209. {
  210.     int        pseudo_code;        /* Code for pseudo mouse event */
  211.     int        button;                /* Which mouse button is it? */
  212.     int        is_click;            /* Is it a mouse button click event? */
  213.     int        is_drag;            /* Is it a mouse drag event? */
  214. } mouse_table[] =
  215. {
  216.     {KE_LEFTMOUSE,        MOUSE_LEFT,        TRUE,    FALSE},
  217.     {KE_LEFTDRAG,        MOUSE_LEFT,        FALSE,    TRUE},
  218.     {KE_LEFTRELEASE,    MOUSE_LEFT,        FALSE,    FALSE},
  219.     {KE_MIDDLEMOUSE,    MOUSE_MIDDLE,    TRUE,    FALSE},
  220.     {KE_MIDDLEDRAG,        MOUSE_MIDDLE,    FALSE,    TRUE},
  221.     {KE_MIDDLERELEASE,    MOUSE_MIDDLE,    FALSE,    FALSE},
  222.     {KE_RIGHTMOUSE,        MOUSE_RIGHT,    TRUE,    FALSE},
  223.     {KE_RIGHTDRAG,        MOUSE_RIGHT,    FALSE,    TRUE},
  224.     {KE_RIGHTRELEASE,    MOUSE_RIGHT,    FALSE,    FALSE},
  225.     {KE_IGNORE,            MOUSE_RELEASE,    FALSE,    TRUE},    /* DRAG without CLICK */
  226.     {KE_IGNORE,            MOUSE_RELEASE,    FALSE,    FALSE}, /* RELEASE without CLICK */
  227.     {0,                    0,                0,        0},
  228. };
  229. #endif /* USE_MOUSE */
  230.  
  231. /*
  232.  * Return the modifier mask bit (MOD_MASK_*) which corresponds to the given
  233.  * modifier name ('S' for Shift, 'C' for Ctrl etc).
  234.  */
  235.     int
  236. name_to_mod_mask(c)
  237.     int        c;
  238. {
  239.     int        i;
  240.  
  241.     for (i = 0; mod_mask_table[i].mod_mask; i++)
  242.         if (TO_LOWER(c) == TO_LOWER(mod_mask_table[i].name))
  243.             return mod_mask_table[i].mod_mask;
  244.     return 0x0;
  245. }
  246.  
  247. /*
  248.  * Decide whether the given key code (K_*) is a shifted special
  249.  * key (by looking at mod_mask).  If it is, then return the appropriate shifted
  250.  * key code, otherwise just return the character as is.
  251.  */
  252.     int
  253. check_shifted_spec_key(c)
  254.     int        c;
  255. {
  256.     int        i;
  257.     int        key0;
  258.     int        key1;
  259.  
  260.     if (mod_mask & MOD_MASK_SHIFT)
  261.     {
  262.         if (c == TAB)            /* TAB is not in the table, K_TAB is */
  263.             return K_S_TAB;
  264.         key0 = KEY2TERMCAP0(c);
  265.         key1 = KEY2TERMCAP1(c);
  266.         for (i = 0; shifted_keys_table[i] != NUL; i += 4)
  267.             if (key0 == shifted_keys_table[i + 2] &&
  268.                                             key1 == shifted_keys_table[i + 3])
  269.                 return TERMCAP2KEY(shifted_keys_table[i],
  270.                                                    shifted_keys_table[i + 1]);
  271.     }
  272.     return c;
  273. }
  274.  
  275. /*
  276.  * Decide whether the given special key is shifted or not.  If it is we
  277.  * return OK and change it to the equivalent unshifted special key code,
  278.  * otherwise we leave it as is and return FAIL.
  279.  */
  280.     int
  281. unshift_special_key(p)
  282.     char_u    *p;
  283. {
  284.     int        i;
  285.  
  286.     for (i = 0; shifted_keys_table[i]; i += 4)
  287.         if (p[0] == shifted_keys_table[i] && p[1] == shifted_keys_table[i + 1])
  288.         {
  289.             p[0] = shifted_keys_table[i + 2];
  290.             p[1] = shifted_keys_table[i + 3];
  291.             return OK;
  292.         }
  293.     return FAIL;
  294. }
  295.  
  296. /*
  297.  * Return a string which contains the name of the given key when the given
  298.  * modifiers are down.
  299.  */
  300.     char_u *
  301. get_special_key_name(c, modifiers)
  302.     int        c;
  303.     int        modifiers;
  304. {
  305.     static char_u string[MAX_KEY_NAME_LEN + 1];
  306.  
  307.     int        i, idx;
  308.     char_u    *s;
  309.     char_u    name[2];
  310.  
  311.     string[0] = '<';
  312.     idx = 1;
  313.  
  314.     /* translate shifted keys into unshifted keys and set modifier */
  315.     if (IS_SPECIAL(c))
  316.     {
  317.         name[0] = KEY2TERMCAP0(c);
  318.         name[1] = KEY2TERMCAP1(c);
  319.         if (unshift_special_key(&name[0]))
  320.             modifiers |= MOD_MASK_SHIFT;
  321.         c = TERMCAP2KEY(name[0], name[1]);
  322.     }
  323.  
  324.     /* translate the modifier into a string */
  325.     for (i = 0; mod_mask_table[i].mod_mask; i++)
  326.         if (modifiers & mod_mask_table[i].mod_mask)
  327.         {
  328.             string[idx++] = mod_mask_table[i].name;
  329.             string[idx++] = (char_u)'-';
  330.         }
  331.  
  332.     /* try to find the key in the special key table */
  333.     i = find_special_key_in_table(c);
  334.     if (i < 0)            /* unknown special key, output t_xx */
  335.     {
  336.         if (IS_SPECIAL(c))
  337.         {
  338.             string[idx++] = 't';
  339.             string[idx++] = '_';
  340.             string[idx++] = KEY2TERMCAP0(c);
  341.             string[idx++] = KEY2TERMCAP1(c);
  342.         }
  343.         /* Not a special key, only modifiers, output directly */
  344.         else
  345.         {
  346.             if (isprintchar(c))
  347.                 string[idx++] = c;
  348.             else
  349.             {
  350.                 s = transchar(c);
  351.                 while (*s)
  352.                     string[idx++] = *s++;
  353.             }
  354.         }
  355.     }
  356.     else                /* use name of special key */
  357.     {
  358.         STRCPY(string + idx, key_names_table[i].name);
  359.         idx = STRLEN(string);
  360.     }
  361.     string[idx++] = '>';
  362.     string[idx] = NUL;
  363.     return string;
  364. }
  365.  
  366. /*
  367.  * Try to find key "c" in the special key table.
  368.  * Return the index when found, -1 when not found.
  369.  */
  370.     int
  371. find_special_key_in_table(c)
  372.     int        c;
  373. {
  374.     int        i;
  375.  
  376.     for (i = 0; key_names_table[i].name != NULL; i++)
  377.         if (c == key_names_table[i].key)
  378.             break;
  379.     if (key_names_table[i].name == NULL)
  380.         i = -1;
  381.     return i;
  382. }
  383.  
  384. /*
  385.  * Find the special key with the given name (the given string does not have to
  386.  * end with NUL, the name is assumed to end before the first non-idchar).
  387.  * If the name starts with "t_" the next two characters are interpreted as a
  388.  * termcap name.
  389.  * Return the key code, or 0 if not found.
  390.  */
  391.     int
  392. get_special_key_code(name)
  393.     char_u    *name;
  394. {
  395.     char_u    *table_name;
  396.     char_u    string[3];
  397.     int        i, j;
  398.  
  399.     /*
  400.      * If it's <t_xx> we get the code for xx from the termcap
  401.      */
  402.     if (name[0] == 't' && name[1] == '_' && name[2] != NUL && name[3] != NUL)
  403.     {
  404.         string[0] = name[2];
  405.         string[1] = name[3];
  406.         string[2] = NUL;
  407.         if (add_termcap_entry(string, FALSE) == OK)
  408.             return TERMCAP2KEY(name[2], name[3]);
  409.     }
  410.     else
  411.         for (i = 0; key_names_table[i].name != NULL; i++)
  412.         {
  413.             table_name = key_names_table[i].name;
  414.             for (j = 0; isidchar(name[j]) && table_name[j] != NUL; j++)
  415.                 if (TO_LOWER(table_name[j]) != TO_LOWER(name[j]))
  416.                     break;
  417.             if (!isidchar(name[j]) && table_name[j] == NUL)
  418.                 return key_names_table[i].key;
  419.         }
  420.     return 0;
  421. }
  422.  
  423.     char_u *
  424. get_key_name(i)
  425.     int        i;
  426. {
  427.     if (i >= KEY_NAMES_TABLE_LEN)
  428.         return NULL;
  429.     return  key_names_table[i].name;
  430. }
  431.  
  432. #ifdef USE_MOUSE
  433. /*
  434.  * Look up the given mouse code to return the relevant information in the other
  435.  * arguments.  Return which button is down or was released.
  436.  */
  437.     int
  438. get_mouse_button(code, is_click, is_drag)
  439.     int        code;
  440.     int        *is_click;
  441.     int        *is_drag;
  442. {
  443.     int        i;
  444.  
  445.     for (i = 0; mouse_table[i].pseudo_code; i++)
  446.         if (code == mouse_table[i].pseudo_code)
  447.         {
  448.             *is_click = mouse_table[i].is_click;
  449.             *is_drag = mouse_table[i].is_drag;
  450.             return mouse_table[i].button;
  451.         }
  452.     return 0;        /* Shouldn't get here */
  453. }
  454.  
  455. /*
  456.  * Return the appropriate pseudo mouse event token (KE_LEFTMOUSE etc) based on
  457.  * the given information about which mouse button is down, and whether the
  458.  * mouse was clicked, dragged or released.
  459.  */
  460.     int
  461. get_pseudo_mouse_code(button, is_click, is_drag)
  462.     int        button;        /* eg MOUSE_LEFT */
  463.     int        is_click;
  464.     int        is_drag;
  465. {
  466.     int        i;
  467.  
  468.     for (i = 0; mouse_table[i].pseudo_code; i++)
  469.         if (button == mouse_table[i].button
  470.             && is_click == mouse_table[i].is_click
  471.             && is_drag == mouse_table[i].is_drag)
  472.         {
  473.             return mouse_table[i].pseudo_code;
  474.         }
  475.     return KE_IGNORE;        /* not recongnized, ignore it */
  476. }
  477. #endif /* USE_MOUSE */
  478.